<?php

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#
#	FILE:			site_specific/shopping_cart.php
#	FUNCTION:		Handles the shopping cart
#	AUTHOR:			Cameron Morrow
#	CREATED:		28/10/2005
#
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

class Cart {

	# Array of current items in cart
	var $cart;

	# Limit to just one of each item
	var $limit_to_one = false;

	# Must be logged in
	var $must_be_logged_in = false;


	/**
	 * Cart() instantiates the Cart
	*/
	function Cart() {

		# Globals
		global $SHOPPING_CART_LIMIT_ONE;
		global $SHOPPING_CART_LOGGED_IN;

		if (!isset($SHOPPING_CART_LIMIT_ONE)) {

			# Set limit
			$this -> setLimitToOne(true);

			$SHOPPING_CART_LIMIT_ONE = true;

		} else {

			# Set limit
			$this -> setLimitToOne($SHOPPING_CART_LIMIT_ONE);
		}

		if (!isset($SHOPPING_CART_LOGGED_IN)) {

			$this -> setMustBeLoggedIn(true);

			$SHOPPING_CART_LOGGED_IN = true;

		} else {

			$this -> setMustBeLoggedIn($SHOPPING_CART_LOGGED_IN);
		}

		# Reset cart
		$this -> resetCart();

		# Check session vars for previously added items
		$this -> fillCartFromSession();

		# Check if adding now
		$this -> checkForAdd();

		# Check for removing an instance now
		$this -> checkForRemove();

		# Check for removing everything
		$this -> checkForRemoveAll();
	}


	/**
	 * resetCart() empties the cart
	*/
	function resetCart() {
		$this -> cart = array();
	}


	/**
	 * fillCartFromSession() refills the cart from the Session
	*/
	function fillCartFromSession() {

		# Globals
		global $PROJECT_CODE;

		# Reset cart
		$this -> resetCart();

		# If it's set
		if (isset($_SESSION[$PROJECT_CODE . "shoppingcart"])) {

			# Get data
			$session_input = $_SESSION[$PROJECT_CODE . "shoppingcart"];

			# If nothing there
			if ($session_input != "") {

				# Explode
				$session_input = explode("|", $session_input);

				# For each
				foreach ($session_input as $item) {

					# Explode
					$item = explode(":", $item);

					# Add to Cart
					$this -> addToCart($item[0]);
				}
			}
		}
	}


	/**
	 * checkForAdd() checks to see if a request to add an item was passed, and if so tries to add it
	 *
	 * @return whether an add occured
	*/
	function checkForAdd() {

		# Globals
		global $PAGE;

		# If GET detected
		if (@$_GET["addtocart"]) {

			# Ensure that this is a valid scene
			if ($PAGE -> getData("p_parent") == "scenes") {

				# Try adding
				$add_success = $this -> addToCart($PAGE -> getID());

				# Feedback
				if ($add_success[0]) {
					addMessage($add_success[1]);
				} else {
					addMessage($add_success[1], 1);
				}
				

				return $add_success[0];

			} else {

				return false;
			}

		} else {

			return false;
		}
	}


	/**
	 * checkForRemove() checks to see if a request to remove an item was passed, and is so tries to remove it
	 *
	 * @return whether a removal occured
	*/
	function checkForRemove() {

		# If GET detected
		if (@$_GET["removefromcart"]) {

			if ($this -> removeFromCart($_GET["removefromcart"], 1)) {
				addMessage("<p>The item was removed from the cart successfully.</p>");
				return true;
			} else {
				addMessage("<p>The item could not be removed from the shopping cart because an error occured. Please try again.</p>", 1);
				return false;
			}
		}
	}


	/**
	 * checkForRemoveAll() checks to see if a request to remove all items from the shopping cart was made, and if so does it
	*/
	function checkForRemoveAll() {

		if (@$_GET["removeallfromcart"]) {
			$this -> resetCart();
			addMessage("<p>The shopping cart was emptied.</p>");
			$this -> updateSession();
		}
	}


	/**
	 * updateSession() updates the session with the current cart contents
	*/
	function updateSession() {

		# Globals
		global $PROJECT_CODE;

		# Create output
		$session_output = array();

		# For each item
		foreach ($this -> cart as $cart_item) {
			$session_output[] = $cart_item["item"] . ":" . $cart_item["count"];
		}

		# Implode
		$session_output = implode("|", $session_output);

		# Save
		$_SESSION[$PROJECT_CODE . "shoppingcart"] = $session_output;
	}


	/**
	 * addToCart() adds an item to the cart
	 *
	 * @param item_id is the ID of the item to add
	 *
	 * @return an array containing the success of the operation, plus a message
	*/
	function addToCart($item_id) {

		# Globals
		global $USER;

		if ($USER -> isLoggedIn() || !$this -> must_be_logged_in) {

			# Check if already added
			foreach ($this -> cart as $cart_count => $cart_item) {
				if ($cart_item["item"] == $item_id) {

					# If can add more than one
					if (!$this -> getLimitToOne()) {

						# Increment count
						$this -> cart[$cart_count]["count"]++;

						# Update session
						$this -> updateSession();

						# Feedback
						return array(true, "<p>Item was added to the cart.</p>");
					} else {

						# Fail
						return array(false, "<p>Item is already in the cart. You can only order one of these items at once.</p>");
					}
				}
			}

			# If not found, add annew
			$this -> cart[] = array("item" => $item_id, "count" => 1);

			# Update session
			$this -> updateSession();

			# Feedback
			return array(true, "<p>Item was added to the cart.</p>");

		} else {

			# Not logged in
			return array(false, "<p>Item was not added to cart as you are not logged in.</p>");
		}
	}


	/**
	 * removeFromCart() removes an item from the cart
	 *
	 * @param item_id is the item ID
	 * @param remove_count is how many to return. If it is left out, all items are returned
	 *
	 * @return the success of the operation
	*/
	function removeFromCart($item_id, $remove_count = false) {
		
		# For each cart item
		foreach ($this -> cart as $cart_count => $cart_item) {

			# If matching
			if ($cart_item["item"] == $item_id) {

				# Are we removing the whole item?
				if ($remove_count === false || $this -> getLimitToOne() || $cart_item["count"] <= $remove_count) {

					# If last one
					if (count($this -> cart) == 1) {

						# Reset
						$this -> resetCart();
						addMessage("<p>Nuked the cart</p>");

					} else {

						# Remove
						array_splice($this -> cart, $cart_count, 1);
					}

					# Update session
					$this -> updateSession();

					# Return
					return true;

				} else {

					if (is_integer($remove_count)) {

						# Decrement counter
						$this -> cart[$cart_count]["count"] -= $remove_count;

						# Update session
						$this -> updateSession();

						# Return
						return true;

					} else {
						return false;
					}
				}
			}
		}
	}


	/**
	 * setLimitToOne() sets the "Limit To One" variable
	 *
	 * @param limit_to_one is whether to limit the cart to one instance of each item
	*/
	function setLimitToOne($limit_to_one = false) {
		$this -> limit_to_one = $limit_to_one;
	}


	/**
	 * getLimitToOne() gets the limit to one variable
	 *
	 * @return the value of limit_to_one
	*/
	function getLimitToOne() {
		return $this -> limit_to_one;
	}


	/**
	 * setMustBeLoggedIn() sets the "Must be logged in" var
	 *
	 * @param must_be_logged_in is whether the user must be logged in to purchase stuff
	*/
	function setMustBeLoggedIn($must_be_logged_in) {
		$this -> must_be_logged_in = $must_be_logged_in;
	}


	/**
	 * getMustBeLoggedIn() gets the value of the "must be logged in" var
	 *
	 * @return the value of must_be_logged_in
	*/
	function getMustBeLoggedIn() {
		return $this -> must_be_logged_in;
	}


	/**
	 * printCart() prints the cart
	 *
	 * @return the output
	*/
	function printCart() {

		$output = "<h3>Cart (" . count($this -> cart) . " distinct items)</h3>";

		$output = "<p>Limited to one instance per item: " . ($this -> getLimitToOne() ? "Yes" : "No") . "</p>";

		foreach ($this -> cart as $cart_count => $cart) {
			$output .= "<p>" . $cart["item"] . " (" . $cart["count"] . " instances)</p>";
		}

		return $output;
	}


	/**
	 * nukeCart nukes the cart
	*/
	function nukeCart() {

		# Globals
		global $PROJECT_CODE;

		# Reset array
		$this -> resetCart();

		# Unset session
		unset($_SESSION[$PROJECT_CODE . "shoppingcart"]);
	}


	/**
	 * getItemCount() gets how many items are in the shopping cart
	 *
	 * @return the number of distinct items in the cart
	*/
	function getItemCount() {
		return count($this -> cart);
	}


	/**
	 * getInstanceCount() gets how many instances of items are in the shopping cart
	 *
	 * @return the total number of instances of items in the shopping cart
	*/
	function getInstanceCount() {
		$count = 0;
		foreach ($this -> cart as $cart_count => $cart_item) {
			$count += $cart_item["count"];
		}
		return $count;
	}


	/**
	 * getCart() gets the cart
	*/
	function getCart() {
		return $this -> cart;
	}
}

?>